Skip to content

Fix: Handle named functions calling other named functions when defined in different order#142

Closed
everettbu wants to merge 3 commits into
mainfrom
main-34542
Closed

Fix: Handle named functions calling other named functions when defined in different order#142
everettbu wants to merge 3 commits into
mainfrom
main-34542

Conversation

@everettbu

@everettbu everettbu commented Dec 12, 2025

Copy link
Copy Markdown

Mirror of facebook/react#34542
Original author: pritjasani08


Summary

This PR fixes issue #33689 where the React Compiler wasn't properly handling cases where named functions call other named functions when they're defined in a "weird order" (i.e., when a function is called before it's declared).

Problem

The getFunctionReferencedBeforeDeclarationAtTopLevel function only checked for function references at the top level scope, but didn't account for nested function calls where one named function calls another named function that's defined later in the code.

Solution

Enhanced the function to:

  1. Check if a function call is within another function that's being compiled
  2. Detect when a named function calls another named function
  3. Properly handle the ordering by adding the called function to referencedBeforeDeclaration when appropriate

Changes

  • Modified: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts

    • Enhanced getFunctionReferencedBeforeDeclarationAtTopLevel function to handle nested function calls
    • Added logic to detect and handle named functions calling other named functions defined later
  • Added: Test fixtures to verify the fix

    • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/named-functions-order.js
    • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/named-functions-order.expect.md

Test Cases

The fix handles these scenarios:

  1. Named function calling another named function defined later in the same component
  2. Nested function calls where inner functions call functions defined later
  3. Complex scenarios with multiple levels of function nesting

Example

function Component(props) {
  function firstFunction() {
    return secondFunction(); // Calls secondFunction before it's declared
  }
  
  function secondFunction() {
    return props.message || "Hello";
  }
  
  return firstFunction();
}

This now works correctly with the React Compiler.

##Checklist

  • I have read the Contributing Guide
  • I have added tests that prove my fix is effective or that my feature works
  • All new and existing tests pass
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation

Fixes #33689

@greptile-apps

greptile-apps Bot commented Dec 12, 2025

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

This PR attempts to fix an issue where the React Compiler doesn't properly handle named functions calling other named functions defined later in the code. The fix adds logic to detect when a function reference occurs within another function being compiled.

Key Changes:

  • Enhanced getFunctionReferencedBeforeDeclarationAtTopLevel to detect nested function calls
  • Added test fixtures for the new behavior
  • Unrelated Flow type definition cleanup in minimist type file

Critical Issues Found:

  • Type Error: The implementation passes a Scope object to getFunctionName() which expects a NodePath. The code uses scope.getFunctionParent() but should use scope.getFunctionParent().path (line 1415-1417)
  • Multiple @ts-ignore comments suppress TypeScript errors instead of fixing underlying type issues
  • The flow-typed/npm/minimist_v1.x.x.js change is unrelated to this PR's purpose

Confidence Score: 1/5

  • This PR has a critical type error that will likely cause runtime failures
  • The implementation has a fundamental type mismatch where Scope.getFunctionParent() returns a Scope but the code passes it to getFunctionName() which expects a NodePath. This will cause the function to fail at runtime. The numerous @ts-ignore comments indicate the author suppressed type checking rather than fixing the issues. While the logic approach seems reasonable, the implementation is broken.
  • compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts requires immediate attention to fix the type error at lines 1415-1417

Important Files Changed

File Analysis

Filename Score Overview
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts 2/5 Added logic to handle nested function calls, but implementation has type errors suppressed with @ts-ignore comments. The scope.getFunctionParent() returns a Scope but is passed to getFunctionName() which expects a NodePath.
compiler/packages/babel-plugin-react-compiler/src/tests/fixtures/compiler/named-functions-calling-order.js 5/5 Test fixture demonstrating the scenario with nested functions calling each other in non-declaration order.
compiler/packages/babel-plugin-react-compiler/src/tests/fixtures/compiler/named-functions-calling-order.expect.md 5/5 Expected output for the test fixture, documenting that the compiler should handle the function ordering correctly.
flow-typed/npm/minimist_v1.x.x.js 4/5 Unrelated Flow type definition cleanup - removed trailing spread operator from object type.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +1415 to +1417
const parentFunction = scope.getFunctionParent();
if (parentFunction !== null) {
const parentFnName = getFunctionName(parentFunction);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: scope.getFunctionParent() returns a Scope, but getFunctionName() expects a NodePath. Should be parentFunction.path

Suggested change
const parentFunction = scope.getFunctionParent();
if (parentFunction !== null) {
const parentFnName = getFunctionName(parentFunction);
const parentFunction = scope.getFunctionParent();
if (parentFunction !== null) {
const parentFnName = getFunctionName(parentFunction.path);
Prompt To Fix With AI
This is a comment left during a code review.
Path: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts
Line: 1415:1417

Comment:
**syntax:** `scope.getFunctionParent()` returns a `Scope`, but `getFunctionName()` expects a `NodePath`. Should be `parentFunction.path`

```suggestion
        const parentFunction = scope.getFunctionParent();
        if (parentFunction !== null) {
          const parentFnName = getFunctionName(parentFunction.path);
```

How can I resolve this? If you propose a fix, please make it concise.

@everettbu

Copy link
Copy Markdown
Author

Upstream PR was closed or merged. Code is synced via branch mirror.

@everettbu everettbu closed this Dec 13, 2025
@everettbu
everettbu deleted the main-34542 branch December 13, 2025 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants